/*******************************************************************************
 * FilePath    : /Software/Examples_Adv_MS1656/adv_app_TxRx_1S/Src/BSP/BSP.c
 * Version     : 1.0
 * Brief       :
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-03-24 15:42:28
 * LastEditors : AndrewHu
 * LastEditTime: 2023-12-28 16:38:25
 * Description : 芯片初始化设置
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define LED_PIN GPIO_PIN_1
#define LED_GPIO GPIOA
#define IRQ_PIN GPIO_PIN_4
#define IRQ_GPIO GPIOB
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
WWDG_HandleTypeDef WWDG_InitStruct = {0};
static FlagStatus wwdg_int = RESET;
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    :
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 16:23:58
 * Description : GPIO统一设置
 ******************************************************************************/
void GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_4 | GPIO_PIN_5);
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);

    // 程序中没有用到的IO要开上、下拉或输出高、低电平，省电
    // GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.OpenDrain = GPIO_PUSHPULL;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_LOW;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN; // GPIO_NOPULL;

    GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_5;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    // 配置LED指示灯,PA1
    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
    GPIO_InitStruct.OpenDrain = GPIO_PUSHPULL;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_LOW;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_LOW;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(LED_GPIO, &GPIO_InitStruct);

    // 配置IRQ中断,PB4
    GPIO_InitStruct.Pin = IRQ_PIN;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    /* Configure Button pin as input */
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(IRQ_GPIO, &GPIO_InitStruct);

    /* Configure Button pin as input with External interrupt */
    GPIO_InitStruct.Mode = EXTI_MODE;
    GPIO_InitStruct.Exti.Enable = GPIO_EXTI_INT_ENABLE;
    GPIO_InitStruct.Exti.EdgeLevelSel = GPIO_EXTI_INT_EDGE;
    GPIO_InitStruct.Exti.RiseFallSel = GPIO_EXTI_INT_LOWFALL;
    HAL_GPIO_Init(IRQ_GPIO, &GPIO_InitStruct);

    __HAL_GPIO_EXTI_CLEAR_FLAG(IRQ_GPIO, IRQ_PIN);
    /* Enable and set Button EXTI Interrupt to the lowest priority */
    HAL_NVIC_SetPriority(GPIOB_IRQn, PRIORITY_LOW);
    HAL_NVIC_EnableIRQ(GPIOB_IRQn);
}
/*******************************************************************************
 * Function    : Error_Handler
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 17:41:26
 * Description : This function is executed in case of error occurrence.
 ******************************************************************************/
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */

    /* USER CODE END Error_Handler_Debug */
}
/*******************************************************************************
 * Function    : User_SystemClock_Config
 * Brief       : 系统时钟初始化函数，初始化之前先复位所有时钟
 * Parameter   : {u8} freq
 * Returns     :
 * Date        : 2020-04-03 15:29:16
 * Description :
 ******************************************************************************/
void User_SystemClock_Config(u8 freq)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    static u8 SystemClock = 0;

    if (SystemClock == freq)
        return; // 当前时钟没变

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HIRC;
    RCC_OscInitStruct.HIRCState = RCC_HIRC_ON;

    switch (freq)
    {
    case SystemClock_8M:
        RCC_OscInitStruct.HIRCCalibrationValue = RCC_HIRCCALIBRATION_8M;
        break;
    case SystemClock_16M:
        RCC_OscInitStruct.HIRCCalibrationValue = RCC_HIRCCALIBRATION_16M;
        break;
    case SystemClock_22M:
        RCC_OscInitStruct.HIRCCalibrationValue = RCC_HIRCCALIBRATION_22M;
        break;
    case SystemClock_24M:
        RCC_OscInitStruct.HIRCCalibrationValue = RCC_HIRCCALIBRATION_24M;
        break;
    default:
        freq = SystemClock_4M;
        RCC_OscInitStruct.HIRCCalibrationValue = RCC_HIRCCALIBRATION_4M;
        break;
    }
    SystemClock = freq; // 标记当前系统时钟

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    /**Initializes the CPU, AHB and APB busses clocks
     */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HIRC;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APBCLKDivider = RCC_PCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
}
/*******************************************************************************
 * Function    : WWdg_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 16:30:40
 * Description : 窗口看门狗设置
 ******************************************************************************/
void WWdg_Init(void)
{
    __HAL_RCC_WWDG_CLK_ENABLE();

    /*set init */
    WWDG_InitStruct.Instance = WWDG;
    WWDG_InitStruct.Init.Reload = 30;         // time=43.7*(Reload-Window)，看门狗时间
    WWDG_InitStruct.Init.Window = 0x05;       // 倒计时比较值
    WWDG_InitStruct.Init.Prescaler = 0xFFFFF; // PCLK=24M,1/24M*0xfffff=43.7ms
    WWDG_InitStruct.Init.INTSet = WWDG_INT_ENABLE;
    /* Set interrupt priority and turn on interrupt*/
    HAL_NVIC_SetPriority(WWDG_IRQn, PRIORITY_LOW);
    HAL_NVIC_EnableIRQ(WWDG_IRQn);

    HAL_WWDG_Init(&WWDG_InitStruct);
}
/*******************************************************************************
 * Function    : WWdg_Refresh
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-25 15:27:39
 * Description : 看么狗清狗
 ******************************************************************************/
void WWdg_Refresh(void)
{
    if (wwdg_int)
    {
        wwdg_int = RESET;
        HAL_WWDG_Refresh(&WWDG_InitStruct);
    }
}
/*******************************************************************************
 * Function    : IsIrqEnabled
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 17:04:51
 * Description : IRQ中断脚IO状态
 ******************************************************************************/
char IsIrqEnabled(void)
{
    return (!HAL_GPIO_ReadPin(IRQ_GPIO, IRQ_PIN));
}
/*******************************************************************************
 * Function    : LED_OnOff
 * Brief       :
 * Parameter   : {u8} onFlag,1-亮，0-灭
 * Returns     :
 * Date        : 2020-03-24 16:36:03
 * Description :
 ******************************************************************************/
void LED_OnOff(u8 onFlag)
{
    if (onFlag)
    {
        HAL_GPIO_WritePin(LED_GPIO, LED_PIN, GPIO_PIN_SET); // high, on
    }
    else
    {
        HAL_GPIO_WritePin(LED_GPIO, LED_PIN, GPIO_PIN_RESET); // low, off
    }
}
/*******************************************************************************
 * Function    : BSP_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2020-03-24 16:36:53
 * Description :
 ******************************************************************************/
void BSP_Init(void)
{
    HAL_Init();
    User_SystemClock_Config(SystemClock_24M);
    GPIO_Init();
    SPIM_Init();
    Uart_Init();
    // WWdg_Init();
    WDG_Init();
    KEY_Init();
}
